{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.1.0\n",
      "sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)\n",
      "matplotlib 3.1.3\n",
      "numpy 1.18.1\n",
      "pandas 1.0.1\n",
      "sklearn 0.22.1\n",
      "tensorflow 2.1.0\n",
      "tensorflow_core.keras 2.2.4-tf\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n产生csv文件\\n'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, tf, keras:\n",
    "    print(module.__name__, module.__version__)\n",
    "\n",
    "'''\n",
    "产生csv文件\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "print(x_train.shape, y_train.shape)\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "print(x_test.shape, y_test.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "x_train_scaled = scaler.fit_transform(x_train)\n",
    "x_valid_scaled = scaler.transform(x_valid)\n",
    "x_test_scaled = scaler.transform(x_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 写入csv文件，其实很简单，使用io函数写入即可\n",
    "## 注意csv格式，使用逗号分隔，最后加上换行 f.write(\"\\n\")\n",
    "output_dir = \"generate_csv\"\n",
    "if not os.path.exists(output_dir):\n",
    "    os.mkdir(output_dir)\n",
    "\n",
    "def save_to_csv(output_dir, data, name_prefix,\n",
    "                header=None, n_parts=10):\n",
    "    path_format = os.path.join(output_dir, \"{}_{:02d}.csv\")\n",
    "    filenames = []\n",
    "    \n",
    "    for file_idx, row_indices in enumerate(\n",
    "        np.array_split(np.arange(len(data)), n_parts)):\n",
    "        part_csv = path_format.format(name_prefix, file_idx)\n",
    "        filenames.append(part_csv)\n",
    "        with open(part_csv, \"wt\", encoding=\"utf-8\") as f:\n",
    "            if header is not None:\n",
    "                f.write(header + \"\\n\")\n",
    "            for row_index in row_indices:\n",
    "                f.write(\",\".join(\n",
    "                    [repr(col) for col in data[row_index]]))\n",
    "                f.write('\\n')\n",
    "    return filenames\n",
    "\n",
    "train_data = np.c_[x_train_scaled, y_train]\n",
    "valid_data = np.c_[x_valid_scaled, y_valid]\n",
    "test_data = np.c_[x_test_scaled, y_test]\n",
    "header_cols = housing.feature_names + [\"MidianHouseValue\"]\n",
    "header_str = \",\".join(header_cols)\n",
    "\n",
    "train_filenames = save_to_csv(output_dir, train_data, \"train\",\n",
    "                              header_str, n_parts=20)\n",
    "valid_filenames = save_to_csv(output_dir, valid_data, \"valid\",\n",
    "                              header_str, n_parts=10)\n",
    "test_filenames = save_to_csv(output_dir, test_data, \"test\",\n",
    "                             header_str, n_parts=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train filenames:\n",
      "['generate_csv/train_00.csv',\n",
      " 'generate_csv/train_01.csv',\n",
      " 'generate_csv/train_02.csv',\n",
      " 'generate_csv/train_03.csv',\n",
      " 'generate_csv/train_04.csv',\n",
      " 'generate_csv/train_05.csv',\n",
      " 'generate_csv/train_06.csv',\n",
      " 'generate_csv/train_07.csv',\n",
      " 'generate_csv/train_08.csv',\n",
      " 'generate_csv/train_09.csv',\n",
      " 'generate_csv/train_10.csv',\n",
      " 'generate_csv/train_11.csv',\n",
      " 'generate_csv/train_12.csv',\n",
      " 'generate_csv/train_13.csv',\n",
      " 'generate_csv/train_14.csv',\n",
      " 'generate_csv/train_15.csv',\n",
      " 'generate_csv/train_16.csv',\n",
      " 'generate_csv/train_17.csv',\n",
      " 'generate_csv/train_18.csv',\n",
      " 'generate_csv/train_19.csv']\n",
      "valid filenames:\n",
      "['generate_csv/valid_00.csv',\n",
      " 'generate_csv/valid_01.csv',\n",
      " 'generate_csv/valid_02.csv',\n",
      " 'generate_csv/valid_03.csv',\n",
      " 'generate_csv/valid_04.csv',\n",
      " 'generate_csv/valid_05.csv',\n",
      " 'generate_csv/valid_06.csv',\n",
      " 'generate_csv/valid_07.csv',\n",
      " 'generate_csv/valid_08.csv',\n",
      " 'generate_csv/valid_09.csv']\n",
      "test filenames:\n",
      "['generate_csv/test_00.csv',\n",
      " 'generate_csv/test_01.csv',\n",
      " 'generate_csv/test_02.csv',\n",
      " 'generate_csv/test_03.csv',\n",
      " 'generate_csv/test_04.csv',\n",
      " 'generate_csv/test_05.csv',\n",
      " 'generate_csv/test_06.csv',\n",
      " 'generate_csv/test_07.csv',\n",
      " 'generate_csv/test_08.csv',\n",
      " 'generate_csv/test_09.csv']\n"
     ]
    }
   ],
   "source": [
    "import pprint\n",
    "print(\"train filenames:\")\n",
    "pprint.pprint(train_filenames)\n",
    "print(\"valid filenames:\")\n",
    "pprint.pprint(valid_filenames)\n",
    "print(\"test filenames:\")\n",
    "pprint.pprint(test_filenames)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tf.Tensor(b'generate_csv/train_01.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_03.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_04.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_02.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_12.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_15.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_13.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_06.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_07.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_05.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_17.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_14.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_09.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_11.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_18.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_19.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_10.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_16.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_00.csv', shape=(), dtype=string)\n",
      "tf.Tensor(b'generate_csv/train_08.csv', shape=(), dtype=string)\n"
     ]
    }
   ],
   "source": [
    "# 1. filename -> dataset\n",
    "# 2. read file -> dataset -> datasets -> merge\n",
    "# 3. parse csv\n",
    "\n",
    "## 将所有的csv文件名组成一个dataset，这里使用list_files，\n",
    "## 为什么要使用list_files 而不是 from_tensor_slices?\n",
    "## 因为该函数可以匹配文件名中的通配符，如 *.cvs 就会把所有的csv文件查找并返回出来\n",
    "## 相当于在from_tensor_slices的基础上，增加了文件遍历检索操作\n",
    "\n",
    "filename_dataset = tf.data.Dataset.list_files(train_filenames)\n",
    "for filename in filename_dataset:\n",
    "    print(filename)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b'-1.0775077698160966,-0.44874070548966555,-0.5680568205591913,-0.14269262164909954,-0.09666677138213985,0.12326468238687088,-0.3144863716683942,-0.4818958888413162,0.978'\n",
      "b'0.801544314532886,0.27216142415910205,-0.11624392696666119,-0.2023115137272354,-0.5430515742518128,-0.021039615516440048,-0.5897620622908205,-0.08241845654707416,3.226'\n",
      "b'0.4853051504718848,-0.8492418886278699,-0.06530126513877861,-0.023379656040017353,1.4974350551260218,-0.07790657783453239,-0.9023632702857819,0.7814514907892068,2.956'\n",
      "b'0.42408210084996534,0.9129633171802288,-0.04437481876046234,-0.15297213746739335,-0.24727627804141977,-0.10539166599677323,0.8612674255663844,-1.3357789003702432,3.955'\n",
      "b'0.09734603446040174,0.7527628439249472,-0.20218964416999152,-0.1954700015215477,-0.4060513603629498,0.006785531677655949,-0.813715166526018,0.656614793197258,1.119'\n",
      "b'-1.2310715896684647,0.9129633171802288,-0.19194563416838628,0.1285146301786722,-0.18739538985158558,0.1460427975617358,-0.7857210284966175,0.656614793197258,0.953'\n",
      "b'-0.2980728090942217,0.3522616607867429,-0.10920507530549702,-0.25055520947444,-0.034064024638222286,-0.006034004264459185,1.080554840130013,-1.0611381656679573,1.514'\n",
      "b'-0.7432054083470616,0.9129633171802288,-0.644320243857189,-0.1479096959813185,0.7398510909061499,0.11427691039226903,-0.7950524078397521,0.6815821327156534,1.438'\n",
      "b'0.4369234889778008,-1.9706452014148417,-0.1664210569911193,0.05486205164394496,-0.8379195842775115,-0.1323988058685803,-0.9956770637171147,0.941242463706905,1.73'\n",
      "b'-1.4803330571456954,-0.6890414153725881,-0.35624704887282904,-0.1725588908792445,-0.8215884329530113,-0.1382309124854157,1.9157132913404298,-1.0211904224385344,0.928'\n",
      "b'-0.47966389100153284,1.874166156711919,0.0560470563410166,-0.006849812286680542,0.02944600829038973,-0.12115399093152514,1.0338979434143465,-1.3407723682739239,2.895'\n",
      "b'-0.03058829290446139,-0.9293421252555106,0.2596214817762415,-0.00601274044096368,-0.5004091235711734,-0.030779867916061836,1.5984463936739026,-1.8151518191233238,1.598'\n",
      "b'-0.8246762898717912,-0.04823952235146133,-0.3448658166118309,-0.08477587145199328,0.5012348243315076,-0.034699996532417135,0.5300034588851571,-0.08741192445075467,0.717'\n",
      "b'-0.49303811681102094,-1.5701440182766375,-0.6933897788607161,0.16277645579446545,0.3279431630548662,-0.08806528786307917,-0.86503775291325,0.6366409215825501,2.033'\n",
      "b'0.21174628471128154,1.1532640270631513,-0.2507761334605016,-0.2564987121705146,-0.6473894854916754,0.017590216427099285,0.7959477701644521,-1.1510205879341566,1.935'\n"
     ]
    }
   ],
   "source": [
    "n_readers = 5\n",
    "dataset = filename_dataset.interleave(\n",
    "    ## A Dataset comprising lines from one or more text files.\n",
    "    ## skip()跳过第一行 heander数据\n",
    "    lambda filename: tf.data.TextLineDataset(filename).skip(1),\n",
    "    cycle_length = n_readers\n",
    ")\n",
    "for line in dataset.take(15):\n",
    "    print(line.numpy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[<tf.Tensor: shape=(), dtype=int32, numpy=1>, <tf.Tensor: shape=(), dtype=int32, numpy=2>, <tf.Tensor: shape=(), dtype=float32, numpy=3.0>, <tf.Tensor: shape=(), dtype=string, numpy=b'4'>, <tf.Tensor: shape=(), dtype=float32, numpy=5.0>]\n"
     ]
    }
   ],
   "source": [
    "# 解析csv文件 tf.io.decode_csv(str,record_defaults)，解析的结果是个list列表\n",
    "# record_defaults 指定每个要解析的参数的类型和默认值\n",
    "# 默认值就是 两个逗号分隔符之间没有数值就是用默认值\n",
    "# tf.io.decode_csv的使用例子\n",
    "sample_str=\"1,2,3,4,5\"\n",
    "\n",
    "# 定义要解析参数的类型，可以传入各种各样的类型，decode_csv会默认的转换为相应的tf类型，定义是很灵活的\n",
    "# 注意点：str不能全是空，数量也不能超过record_default的类型指定数量\n",
    "record_defaults=[\n",
    "    tf.constant(0,dtype=tf.int32), # 指定以一个参数默认值是0，类型是tf.int32类型\n",
    "    0, # 指定默认值是0，类型是tf.int32\n",
    "    np.nan, # 指定默认值是nan，类型是tf.float32(nan的默认类型就是float32)\n",
    "    \"hello\", # 指定默认值是hello，类型是tf.string\n",
    "    tf.constant([]), # 默认值是空，类型是tf.constant的默认类型tf.float32\n",
    "]\n",
    "parsed_fields=tf.io.decode_csv(sample_str,record_default)\n",
    "print(parsed_fields)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Field 4 is required but missing in record 0! [Op:DecodeCSV]\n"
     ]
    }
   ],
   "source": [
    "## csv数据不能全是空\n",
    "try:\n",
    "    parsed_fields = tf.io.decode_csv(',,,,', record_defaults)\n",
    "except tf.errors.InvalidArgumentError as ex:\n",
    "    print(ex)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Expect 5 fields but have 7 in record 0 [Op:DecodeCSV]\n"
     ]
    }
   ],
   "source": [
    "## 解析格式长度 要和 数据长度匹配\n",
    "try:\n",
    "    parsed_fields = tf.io.decode_csv('1,2,3,4,5,6,7', record_defaults)\n",
    "except tf.errors.InvalidArgumentError as ex:\n",
    "    print(ex)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(<tf.Tensor: shape=(8,), dtype=float32, numpy=\n",
       " array([-0.9868721 ,  0.8328631 , -0.18684709, -0.1488895 , -0.45323023,\n",
       "        -0.11504996,  1.6730974 , -0.74654967], dtype=float32)>,\n",
       " <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.138], dtype=float32)>)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def parse_csv_line(line, n_fields = 9):\n",
    "    defs = [tf.constant(np.nan)] * n_fields\n",
    "    parsed_fields = tf.io.decode_csv(line, record_defaults=defs)\n",
    "    x = tf.stack(parsed_fields[0:-1])\n",
    "    y = tf.stack(parsed_fields[-1:])\n",
    "    return x, y\n",
    "\n",
    "parse_csv_line(b'-0.9868720801669367,0.832863080552588,-0.18684708416901633,-0.14888949288707784,-0.4532302419670616,-0.11504995754593579,1.6730974284189664,-0.7465496877362412,1.138',\n",
    "               n_fields=9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x:\n",
      "<tf.Tensor: shape=(8,), dtype=float32, numpy=\n",
      "array([-0.097193  , -1.2497431 ,  0.36232963,  0.02690608,  1.0338118 ,\n",
      "        0.04588159,  1.3418335 , -1.635387  ], dtype=float32)>\n",
      "y:\n",
      "<tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.832], dtype=float32)>\n",
      "x:\n",
      "<tf.Tensor: shape=(8,), dtype=float32, numpy=\n",
      "array([-0.32652634,  0.4323619 , -0.09345459, -0.08402992,  0.8460036 ,\n",
      "       -0.02663165, -0.56176794,  0.1422876 ], dtype=float32)>\n",
      "y:\n",
      "<tf.Tensor: shape=(1,), dtype=float32, numpy=array([2.431], dtype=float32)>\n"
     ]
    }
   ],
   "source": [
    "# 1. filename -> dataset\n",
    "# 2. read file -> dataset -> datasets -> merge\n",
    "# 3. parse csv\n",
    "def csv_reader_dataset(filenames, n_readers=5,\n",
    "                       batch_size=32, n_parse_threads=5,\n",
    "                       shuffle_buffer_size=10000):\n",
    "    dataset = tf.data.Dataset.list_files(filenames)\n",
    "    dataset = dataset.repeat()\n",
    "    dataset = dataset.interleave(\n",
    "        lambda filename: tf.data.TextLineDataset(filename).skip(1),\n",
    "        cycle_length = n_readers\n",
    "    )\n",
    "    dataset.shuffle(shuffle_buffer_size)\n",
    "    dataset = dataset.map(parse_csv_line,\n",
    "                          num_parallel_calls=n_parse_threads)\n",
    "#     dataset = dataset.batch(batch_size)\n",
    "    return dataset\n",
    "\n",
    "train_set = csv_reader_dataset(train_filenames, batch_size=3)\n",
    "for x_batch, y_batch in train_set.take(2):\n",
    "    print(\"x:\")\n",
    "    pprint.pprint(x_batch)\n",
    "    print(\"y:\")\n",
    "    pprint.pprint(y_batch)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_size = 32\n",
    "train_set = csv_reader_dataset(train_filenames,\n",
    "                               batch_size = batch_size)\n",
    "valid_set = csv_reader_dataset(valid_filenames,\n",
    "                               batch_size = batch_size)\n",
    "test_set = csv_reader_dataset(test_filenames,\n",
    "                              batch_size = batch_size)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "348/348 [==============================] - 2s 6ms/step - loss: 2.6241 - val_loss: 1.1120\n",
      "Epoch 2/100\n",
      "348/348 [==============================] - 2s 6ms/step - loss: 0.8670 - val_loss: 0.8067\n",
      "Epoch 3/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.7344 - val_loss: 0.7604\n",
      "Epoch 4/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.6742 - val_loss: 0.7299\n",
      "Epoch 5/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.6572 - val_loss: 0.6977\n",
      "Epoch 6/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.6285 - val_loss: 0.6710\n",
      "Epoch 7/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.6049 - val_loss: 0.6499\n",
      "Epoch 8/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.5813 - val_loss: 0.6281\n",
      "Epoch 9/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.5625 - val_loss: 0.6099\n",
      "Epoch 10/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.5458 - val_loss: 0.5940\n",
      "Epoch 11/100\n",
      "348/348 [==============================] - 2s 4ms/step - loss: 0.5371 - val_loss: 0.5806\n",
      "Epoch 12/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.5378 - val_loss: 0.5679\n",
      "Epoch 13/100\n",
      "348/348 [==============================] - 1s 3ms/step - loss: 0.5019 - val_loss: 0.5596\n",
      "Epoch 14/100\n",
      "348/348 [==============================] - 1s 3ms/step - loss: 0.5163 - val_loss: 0.5459\n",
      "Epoch 15/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4920 - val_loss: 0.5392\n",
      "Epoch 16/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.4869 - val_loss: 0.5332\n",
      "Epoch 17/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4916 - val_loss: 0.5275\n",
      "Epoch 18/100\n",
      "348/348 [==============================] - 2s 4ms/step - loss: 0.4789 - val_loss: 0.5205\n",
      "Epoch 19/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4913 - val_loss: 0.5207\n",
      "Epoch 20/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4698 - val_loss: 0.5092\n",
      "Epoch 21/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4691 - val_loss: 0.5055\n",
      "Epoch 22/100\n",
      "348/348 [==============================] - 2s 7ms/step - loss: 0.4668 - val_loss: 0.5010\n",
      "Epoch 23/100\n",
      "348/348 [==============================] - 3s 8ms/step - loss: 0.4623 - val_loss: 0.4972\n",
      "Epoch 24/100\n",
      "348/348 [==============================] - 2s 6ms/step - loss: 0.4665 - val_loss: 0.4945\n",
      "Epoch 25/100\n",
      "348/348 [==============================] - 2s 6ms/step - loss: 0.4605 - val_loss: 0.4967\n",
      "Epoch 26/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.4562 - val_loss: 0.4880\n",
      "Epoch 27/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4534 - val_loss: 0.4830\n",
      "Epoch 28/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.4467 - val_loss: 0.4856\n",
      "Epoch 29/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4513 - val_loss: 0.4831\n",
      "Epoch 30/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4477 - val_loss: 0.4769\n",
      "Epoch 31/100\n",
      "348/348 [==============================] - 1s 3ms/step - loss: 0.4456 - val_loss: 0.4745\n",
      "Epoch 32/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4395 - val_loss: 0.4724\n",
      "Epoch 33/100\n",
      "348/348 [==============================] - 2s 5ms/step - loss: 0.4529 - val_loss: 0.4739\n",
      "Epoch 34/100\n",
      "348/348 [==============================] - 2s 4ms/step - loss: 0.4327 - val_loss: 0.4740\n",
      "Epoch 35/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4381 - val_loss: 0.4702\n",
      "Epoch 36/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4454 - val_loss: 0.4644\n",
      "Epoch 37/100\n",
      "348/348 [==============================] - 1s 4ms/step - loss: 0.4303 - val_loss: 0.4674\n"
     ]
    }
   ],
   "source": [
    "model = keras.models.Sequential([\n",
    "    keras.layers.Dense(30, activation='relu',\n",
    "                       input_shape=[8]),\n",
    "    keras.layers.Dense(1),\n",
    "])\n",
    "model.compile(loss=\"mean_squared_error\", optimizer=\"sgd\")\n",
    "callbacks = [keras.callbacks.EarlyStopping(\n",
    "    patience=5, min_delta=1e-2)]\n",
    "\n",
    "## 模型传入的数据时 tensor类型的数据\n",
    "## 为为什么之前都没看到模型指定batch_size?\n",
    "## 因为之前传入的数据，都是二维的，而模型会使用默认的batch_size，把数据自动的按照batch_size分割，直到所有的dataset结束\n",
    "history = model.fit(train_set,\n",
    "                    validation_data = valid_set,\n",
    "                    steps_per_epoch = 11160 // batch_size,\n",
    "                    validation_steps = 3870 // batch_size,\n",
    "                    epochs = 100,\n",
    "                    callbacks = callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "161/161 [==============================] - 0s 3ms/step - loss: 0.4601\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.46014384971642347"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(test_set, steps = 5160 // batch_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
